package edu.hawaii.halealohacli.command;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Monitors the power of a given tower based on a optional time interval given. Default time
 * interval if none is provided is 10 seconds.
 * 
 * @author mitchellkupfer
 * 
 */
public class MonitorPower implements Command {
  private String name;
  private String usage;
  private String description;
  // private String errorMsg;
  protected WattDepotClient client;
  protected String nameFromUser;
  protected int interval;
  protected boolean exitMonitor;
 

  // private double pwrReading;

  /**
   * Default constructor.
   */
  public MonitorPower() {
    this.name = "monitor-power";
    this.usage = "monitor-power [tower | lounge] [interval]";
    this.description =
        "This command prints out a timestamp and the current"
            + " power for [tower | lounge] every [interval] seconds.";
    // this.errorMsg = "monitor-power was incorrectly used";
    this.interval = 10000;
    this.exitMonitor = true;
  }

  /**
   * Initializes this command with a healthy WattDepot client.
   * 
   * @param client A healthy WattDepot client used to initialize the command
   * @param args * Arguments required by the command for execution
   * @return Weather or not the arguments passed was accepted by the command initialization
   */
  @Override
  public boolean initializeCommand(WattDepotClient client, String[] args) {
    // set a client
    this.client = client;

    if (args.length < 1 || args.length > 2) {
      System.out.format("The arguments are invalid " + "(Enter \"help\" to see command usage)");
      return false;
    }

    // if a interval was specific, cast it and save it.
    this.nameFromUser = args[1];

    if (args.length == 3) {
      try {
        this.interval = 1000 * Integer.parseInt(args[2]);
      }
      catch (Exception e) {
        System.out.println("Invalid interval, please enter interval in seconds.");
        return false;
      }
    }
    getData();
    return true;
  }

  /**
   * Gets the power data from the given tower at the specified interval. Stops monitoring power in a
   * user enter any input.
   * 
   * @return If an error occurs returns false.
   */
  public boolean getData() {

    // creates a new runnable for a thread that will execute then delay.
    Runnable run = new Runnable() {
      public void run() {
        try {
          while (exitMonitor) {

            printer();
            Thread.sleep(interval);

          }
        }
        catch (InterruptedException iex) {
          exitMonitor = false;
        }
      }
    };

    Thread thread = new Thread(run);
    thread.start();

    try {
      while (System.in.available() == 0) {
        // Annoying code to  avoid a PMD error.
        exitMonitor = false;
        exitMonitor = true;
      }
    }
    catch (IOException e) {
      exitMonitor = false;
      return false;
    }

    exitMonitor = false;
    return true;

  }

  /**
   * Prints out the values from each interval.
   */
  public void printer() {

    // code from currentPower class
    try {
      SourceData dataModule;
      long dTime;
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MMM-dd kk:mm:ss", Locale.US);
      Source source;
      XMLGregorianCalendar timestamp;
      source = client.getSource(nameFromUser);
      timestamp = client.getLatestSensorData(nameFromUser).getTimestamp();
      dataModule = new SourceData(source.getName());
      dataModule.setPowerConsumed(client.getPowerConsumed(source.getName(), timestamp));
      // pwrReading = dataModule.getPowerConsumed();
      dTime = timestamp.toGregorianCalendar().getTimeInMillis();
      dataModule.setTime(format.format(dTime));

      System.out.format("%s %s %s %s %s %s", dataModule.getName(), "'s power as of",
          dataModule.getTime(), "was ", dataModule.getPowerConsumed(), ".\n");
    }

    catch (Exception e) {
      System.out.println("Cannot connect to Tower " + nameFromUser + e);
      exitMonitor = false;
    }
  }

  /**
   * Returns the name of this command.
   * 
   * @return the name of this command
   */
  @Override
  public String getName() {
    return name;
  }

  /**
   * Returns the usage syntax of this command.
   * 
   * @return the usage syntax of this command
   */
  @Override
  public String getUsage() {
    return usage;
  }

  /**
   * Returns the description of this command.
   * 
   * @return a description of this command
   */
  @Override
  public String getDescription() {
    return description;
  }

  /**
   * Prints the results of executing this command.
   */
  public void printResults() {
    System.out.println("Monitor-Power Has Been Exited, The Following Two Lines Can Be Ignored");
  }
}
